"""
Case Type   : 资源池化
Case Name   : 循环增删改查，主备数据查询结果一致，验证主备快照一致
Create At   : 2024.1.3
Owner       : wx1133724
Description :
    1、设置ss_enable_bcast_snapshot=on
    2、创建表并插入数据
    3、循环增删改查
    4、主备数据查询
    5、清理环境
Expect      :
    1、设置成功
    2、成功
    3、成功
    4、主备数据查询结果一致，验证主备快照一致
    5、成功
"""

import os
import unittest
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger


class SharedStorage(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.com = Common()
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.st1_sh = CommonSH('Standby1DbUser')
        self.st2_sh = CommonSH('Standby2DbUser')
        self.param = 'ss_enable_bcast_snapshot'
        self.src = self.com.show_param(self.param)
        self.tb_name = 't_snapshot_case0008'

        self.log.info('------检查数据库状态是否正常------')
        status = self.pri_sh.exec_cm_ctl('query', '-Cv')
        self.assertIn("cluster_state   : Normal", status)

    def test_shared_storage(self):
        text = '-----step1:使用gs_guc set设置ss_enable_bcast_snapshot=on;' \
               'expect:设置成功-----'
        self.log.info(text)
        set_param = self.pri_sh.execute_gsguc('set',
                                              self.constant.GSGUC_SUCCESS_MSG,
                                              f"{self.param} = on")
        self.log.info(set_param)
        self.assertTrue(set_param, '参数修改失败')

        db_restart = self.pri_sh.exec_cm_ctl('stop && cm_ctl start', '-t 60')
        self.log.info(db_restart)
        self.assertIn(self.constant.cm_start_success_msg, db_restart,
                      '执行失败' + text)

        param_res = self.com.show_param(self.param)
        self.log.info(param_res)
        self.assertEqual('on', param_res, '执行失败' + text)

        text = '-----step2:创建表并插入数据;expect:成功-----'
        self.log.info(text)
        cmd = f'''drop table if exists {self.tb_name};
        create table {self.tb_name}(id int, c1 text) with(segment=on);
        insert into {self.tb_name} select generate_series(1,1000), 'snapshot';
        '''
        res = self.pri_sh.execut_db_sql(cmd)
        self.log.info(res)
        self.assertIn(self.constant.DROP_TABLE_SUCCESS, res, '执行失败' + text)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, res, '执行失败' + text)
        self.assertIn(self.constant.INSERT_SUCCESS_MSG, res, '执行失败' + text)

        text = '-----step3:循环增删改查;expect:成功-----'
        self.log.info(text)
        cmd = f'''insert into {self.tb_name} select generate_series(1,1000), 
        'snapshot';
        update {self.tb_name} set id=1 where c1='test';
        select count(*) from {self.tb_name};
        delete from {self.tb_name};
        '''
        res = self.pri_sh.cycle_exec_sql(cmd, 100)
        self.log.info(res)
        self.assertTrue(res)

        text = '-----step4:主备数据查询;' \
               'expect:主备数据查询结果一致，验证主备快照一致-----'
        self.log.info(text)
        cmd = f'select checksum({self.tb_name}::text)from {self.tb_name}'
        pri_res = self.pri_sh.execut_db_sql(cmd)
        self.log.info(pri_res)
        st1_res = self.st1_sh.execut_db_sql(cmd)
        self.log.info(st1_res)
        st2_res = self.st2_sh.execut_db_sql(cmd)
        self.log.info(st2_res)
        self.assertEqual(pri_res, st1_res, st2_res)

    def tearDown(self):
        text = '-----step5:恢复ss_enable_bcast_snapshot默认值;expect:恢复成功-----'
        self.log.info(text)
        recov_param = self.pri_sh.execute_gsguc('set',
                                              self.constant.GSGUC_SUCCESS_MSG,
                                              f"{self.param} = '{self.src}'")
        self.log.info(recov_param)

        self.log.info('-----重启集群-----')
        restart = self.pri_sh.exec_cm_ctl('stop && cm_ctl start')
        self.log.info(restart)

        self.assertTrue(recov_param, '参数修改失败')
        self.assertIn(self.constant.cm_start_success_msg, restart,
                      '执行失败' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
